home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1998 July
/
EnigmA AMIGA RUN 29 (1998)(G.R. Edizioni)(IT)[!][issue 1998-07 & 08].iso
/
earcd
/
utils
/
madhouse
/
developer
/
c
/
examples
/
water
/
water.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-12-21
|
9KB
|
516 lines
// Water.c
// Used as a demo for blanker programming.
// Compiled with MaxonC++ 4 Dev.
// OS-Includes
#include <intuition/screens.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/dos_protos.h>
#include <pragma/dos_lib.h>
#include <pragma/exec_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/madblankersupport_lib.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define NDEBUG 1
#include <assert.h>
// Variablen
struct Screen *scr = NULL;
struct Window *win = NULL;
struct Library *IntuitionBase = NULL;
struct Library *GfxBase = NULL;
struct Library *madblankersupportbase = NULL;
struct RastPort *rast;
struct ViewPort *view;
struct RastPort col[256];
struct RastPort col0;
UWORD col_anz;
UWORD BlPalette[] = {
0x0000,
0x0666,
0x0999,
0x0FFF
};
//ULONG ScrMode = 0x8000; // pAL highres
//ULONG ScrMode = 0x99004; // dblNTSC flickerfixed.
ULONG ScrMode = 0; // PAL lowres
UWORD SWidth;
UWORD SHeight;
UWORD SWidth2;
UWORD SHeight2;
UWORD SWidth16;
UWORD SHeight16;
ULONG SDepth = 3;
short kanz = 10;
UWORD xscale; // = 16; // 16 entspricht 640 Pixeln
UWORD yscale; // = 16; // 16 entspricht 400 Pixeln
UWORD maxx, maxy;
const short yfact = 10;
BOOL OS3 = FALSE;
// Preferences
UWORD Drop_anz = 500; // min. 20!
UWORD Time = 15;
UWORD bounce_type = 0;
#define BT_NONE 0
#define BT_BOTTOM 1
#define BT_ONCE 2
#define BT_TWO 3
// Libs, Screen, Window
void close_blanker()
{
if( win ) CloseWindow( win );
if( scr ) CloseScreen( scr );
scr = NULL;
if( GfxBase ) CloseLibrary( GfxBase );
if( IntuitionBase ) CloseLibrary( IntuitionBase );
}
BOOL setup_blanker()
{
IntuitionBase = OpenLibrary("intuition.library",37);
if( !IntuitionBase ) {
return FALSE;
}
GfxBase = OpenLibrary("graphics.library",37);
if( !GfxBase ) {
return FALSE;
}
if( GfxBase->lib_Version >= 39 ) OS3 = TRUE;
scr = OpenScreenTags(NULL,
SA_Depth, SDepth,
SA_Interleaved, FALSE,
SA_DisplayID, ScrMode,
SA_Title, "Water",
SA_Overscan, OSCAN_STANDARD,
TAG_DONE);
col_anz = 1 << SDepth;
if( !scr ) {
MBS_ErrorReport( "Couldn't open Screen!" );
return FALSE;
}
SWidth = scr->Width;
SHeight = scr->Height;
SWidth2 = SWidth / 2;
SHeight2 = SHeight / 2;
xscale = 10240 / SWidth;
yscale = 6400 / SHeight;
SWidth16 = SWidth * xscale;
SHeight16 = SHeight * yscale;
view = &scr->ViewPort;
SetRGB4( view, 0, 0,0,0 );
win = OpenWindowTags(NULL,
WA_AutoAdjust, TRUE,
WA_NoCareRefresh, TRUE,
WA_CustomScreen, scr,
WA_Flags, WFLG_RMBTRAP,
WA_Borderless, TRUE,
WA_Activate, TRUE,
TAG_DONE );
if( !win ) {
MBS_ErrorReport( "Couldn't open Window!");
return FALSE;
}
MBS_ClearMousePointer( scr );
rast = &(scr->RastPort);
col0 = *win->RPort;
SetAPen( &col0, 0);
maxx = 10240 - xscale*2 - 1;
for( UWORD y = 5000; y < 6400; y++ ) {
if( WritePixel( &col0, 0, y / yscale ))
break;
}
maxy = y;
col[0] = *win->RPort;
SetAPen( &col[0], 0);
for( short i=1; i<col_anz; i++) {
col[i] = *win->RPort;
SetAPen( &col[i], i);
if( OS3 ) {
SetRGB32( view, i, i*255/col_anz << 24, i*255/col_anz << 24, 255 << 24);
} else {
SetRGB4( view, i, i*15/col_anz, i*15/col_anz, 15 );
}
}
return TRUE;
}
UWORD maxsteps = 0;
WORD above_basestep, middle_basestep, below_basestep;
WORD range_left, range_right;
class GlobalInitValues
{
public:
WORD xbase, xmaxadd,
ybase, ymaxadd,
xdirbase, xdirmaxadd,
ydirbase, ydirmaxadd;
void Renew();
};
void GlobalInitValues::Renew()
{
xdirbase = Random(150)-75; //Random(100)-50;
xdirmaxadd = Random(40)+1;
xdirbase -= xdirmaxadd / 2;
if( abs(xdirbase + xdirmaxadd) > 100 ) {
xdirbase /= 2;
xdirmaxadd /= 2;
}
ydirbase = Random(100)-20-40;
ydirmaxadd = 3; //Random(5)-3;
if( xdirbase > 0) {
xbase = Random(3000) + 900;
xmaxadd = Random(1000)+40; // Random(20);
} else {
xbase = Random(3000) + 6000;
xmaxadd = Random(1000)+40; // Random(20);
}
ybase = 300; // + (abs(ydirbase)+20)*10;
if( ydirbase < 0 ) {
ybase = 300 - ydirbase*30;
}
ymaxadd = 100; //Random(3);
if( Random(10) == 1 ) {
xdirbase /= 10;
xmaxadd = 2000 + Random(5000);
xbase = 1000;
}
// Hier gleich mit erledigt...
middle_basestep = 2000 + Random(2500);
above_basestep = 2000 + Random(700);
below_basestep = 2700 + Random(2800);
UWORD range_size = 2000 + Random( 7000 );
range_left = Random( 10240 - range_size );
range_right = range_left + range_size;
}
class GlobalInitValues GIV;
class WaterDrop
{
private:
WORD xpos, ypos;
WORD xdir, ydir;
RastPort *col_used;
UWORD col_num;
UWORD life;
UWORD bounce_cnt;
public:
void GlobalInit();
inline void CalcMove();
UWORD TestMove();
void ForwardMoves( UWORD steps );
void Move();
void Reset( WORD x, WORD y );
void SetDirection( WORD xd, WORD yd );
};
void WaterDrop::GlobalInit()
{
Reset( GIV.xbase + Random(GIV.xmaxadd), GIV.ybase+Random(GIV.ymaxadd) );
SetDirection( Random(GIV.xdirmaxadd)+GIV.xdirbase, Random(GIV.ydirmaxadd)+GIV.ydirbase );
//Reset( 1000+Random(140), 300+Random(50) );
//SetDirection( Random(20)+30, Random(5)+10 );
life = 0;
bounce_cnt = 0;
}
inline void WaterDrop::CalcMove()
{
xpos += xdir;
ypos += ydir++;
BOOL flag = FALSE;
switch( bounce_type ) {
// case BT_NONE:
// break;
case BT_BOTTOM:
flag = ypos > maxy && bounce_cnt < 2;
break;
case BT_ONCE:
flag = (ypos > middle_basestep && bounce_cnt == 0 );
break;
case BT_TWO:
flag = (ypos > above_basestep && xpos > range_left && xpos < range_right && bounce_cnt == 0)
|| (ypos > below_basestep && bounce_cnt < 2);
break;
}
if( flag ) {
ydir = -( (ydir * 1) / 3 );
ydir -= Random(4);
ypos += ydir++;
xdir /= 4;
xdir += Random(30)-15;
bounce_cnt++;
//if( ydir > -rebounce ) ypos = maxy+1000;
}
}
UWORD WaterDrop::TestMove()
{
GlobalInit();
for( UWORD cnt = 0; ; cnt++ ) {
CalcMove();
if( (ypos > maxy) || (xpos < 0) || (xpos >maxx) || (ypos < 0) )
return cnt;
}
}
void WaterDrop::ForwardMoves( UWORD steps )
{
// ein kleiner Vorlauf, damit die Dinger sich verteilen lassen.
GlobalInit();
for( UWORD cnt = 0; cnt < steps; cnt++ ) {
CalcMove();
life++;
if( life > (maxsteps / col_anz) ) {
life = 0;
if( col_num < col_anz - 1 ) col_num++;
col_used = &col[col_num];
}
if( (ypos > maxy) || (xpos < 0) || (xpos >maxx) || (ypos < 0) )
GlobalInit();
}
}
void WaterDrop::Move()
{
WritePixel( &col0, xpos / xscale, ypos / yscale );
CalcMove();
life++;
if( life > (maxsteps / col_anz) ) {
life = 0;
if( col_num < col_anz - 1 ) col_num++;
col_used = &col[col_num];
}
if( WritePixel( col_used, xpos / xscale, ypos / yscale ) == -1 ) {
GlobalInit();
}
}
void WaterDrop::Reset( WORD x, WORD y )
{
WritePixel( &col0, xpos / xscale, ypos / yscale );
xpos = x;
ypos = y;
UWORD c = 1;
col_used = &col[c];
col_num = c;
}
void WaterDrop::SetDirection( WORD xd, WORD yd )
{
xdir = xd;
ydir = yd;
}
class WaterDrop *WD;
void DistributeWD()
{
maxsteps = 0;
UWORD thisanz = 0;
for( short n = 0; n < 20; n++ ) {
thisanz = WD[n].TestMove();
maxsteps += thisanz;
//if( thisanz > maxsteps ) maxsteps = thisanz;
}
maxsteps /= 20;
for( n = 0; n < Drop_anz; n++ ) {
WD[n].ForwardMoves( (maxsteps * n) / Drop_anz );
}
}
// Hauptprogramm
void ende()
{
close_blanker();
if( madblankersupportbase ) {
MBS_Quit();
CloseLibrary( madblankersupportbase );
}
exit( 0 );
}
void main()
{
BOOL quit = FALSE;
madblankersupportbase = OpenLibrary(MADBLANKERSUPPORT_NAME,MADBLANKERSUPPORT_VMIN);
if( !madblankersupportbase ) exit(20);
//MBS_DebugMode();
if( !MBS_GetBlankjob() ) {
CloseLibrary( madblankersupportbase );
exit(20);
}
ScrMode = MBS_GetScreenmodePrefs( 0 /*0x99004*/ );
SDepth = MBS_GetScreendepthPrefs( 2 );
Drop_anz = MBS_GetPrefs( "drops", 400 );
Time = MBS_GetPrefs( "duration", 35 );
bounce_type = MBS_GetPrefs( "bouncetype", 1 );
WD = new WaterDrop [ Drop_anz ];
if( ! WD ) {
MBS_Quit();
CloseLibrary( madblankersupportbase );
exit(0);
}
if( setup_blanker() ) {
UWORD cnt = 0;
BOOL conti = TRUE;
time_t starttime;
while( !MBS_ContinueBlanking() ) {
cnt = 0;
conti = TRUE;
RectFill( &col0, 0, 0, SWidth-1, SHeight-1 );
GIV.Renew();
DistributeWD();
starttime = time(NULL);
while( !MBS_ContinueBlanking() && conti ) {
cnt++;
if( cnt == 15 ) {
cnt = 0;
conti = (time(NULL) - starttime) < Time;
}
WaterDrop *cursor = &WD[0];
for( short n = 0; n < Drop_anz; n++ ) {
cursor->Move();
cursor++;
}
}
}
}
close_blanker();
MBS_Quit();
CloseLibrary( madblankersupportbase );
}